/**
 * \defgroup Map Map
 * \brief Everything to do with the \a Map and terrain.
 * 
 * A group used to bundle together everything that has to do with \a Map and terrain, the game field.
 * 
 * \file Map.h
 * \brief Header file for the \a Map class.
 * \ingroup Map
 */

#ifndef MAP_H
#define MAP_H

#define NUM_ROWS 14
///< Amount of rows on a \a Map.
#define NUM_COLS 15
///< Amount of columns on a \a Map.

class AlgFloyd;
class Field;
class Unit;

#include<QList>
#include<QObject>

//15 x 14 fields, every 2nd row is .5 to the east

/**
 * \class Map
 * \brief Class used to represent the game map.
 * \ingroup Map
 */

class Map: public QObject{
Q_OBJECT
public:
	Map();///<Constructor. Requires no arguments and initializes a randomized \a Map.
	~Map();///<Destructor.
	
	bool doTurn();///<Causes the current \a Unit to do its turn. \return Wether or not the next \a Unit can still take a turn.
	
	void setTeams(QList<Unit*> teamA, QList<Unit*> teamB );///<Initializes the teams. \param teamA List of team A's units. \param teamB List of team B's units.
	
	Field *field(int row, int col)const{ return m_fields[row][col]; }///<Returns one particular \a Field. \param row Row :-) \param col Col :-)
	
	QList<Unit*> getEnemyUnits(Unit *unit)const;///<Returns enemy units. \param unit The \a Unit whose enemies to return.
	QList<Unit*> getFriendlyUnits(const Unit *unit, bool includeSelf = false)const;///<Returns friendly units. \param unit The \a Unit whose friends to return. \param includeSelf Decides wether or not we're a friend to ourself :-)
	QList<Field*> getAccessibleFields(const Unit *unit)const;///<Returns all \a Field s this \a Unit can reach. \param unit The \a Unit for whom to calculate which fields it can reach.
	
	void moveUnit(Unit *unit, Field *dest);///<Causes a \a Unit to be moved. \param unit The \a Unit to be moved. \param dest The destination \a Field.
	
	void remove(Unit *unit);///<Removes a \a Unit from this \a Map. \param unit The \a Unit to be removed.
	
	const QList<Unit*> &turnSequence()const{ return m_turnSequence; }///<Returns the turn sequence, first entry being the next unit to get a turn.
	
	int travelDistance(const Field *from, const Field *to)const;///<Returns the actual range value it requires to travel. \param from From :-) \param to To :-)
signals:
	void unitDied(Unit *unit);///<Emitted when a \a Unit dies. \param unit The dead \a Unit.
	void unitDamaged(Unit *unit);///<Emitted when a \a Unit is damaged. \param unit The damaged \a Unit.
	void turnEnded(Unit *unit);///<Emitted when a \a Unit 's turn ended. \param unit The \a Unit whose turn ended.
private slots:
	void slotUnitTookDamage();///<Called when a unit took damaged. Used to cause emission of the unitDied and unitDamaged signals.
private:
	QList<Unit*> m_teamA;///<Team A.
	QList<Unit*> m_teamB;///<Team B.
	QList<Unit*> m_fallenUnits;///<Container for dead'uns.
	QList<Unit*> m_turnSequence;///<Turn sequence, first entry being the next \a Unit to have a turn.
	Field ***m_fields;///<The fields for this game, like Field*[14][15]
	AlgFloyd *m_floyd;///<The floyd algorithm, or rather a container for its result.
	
	void initTurns();///<Causes m_turnSequence to be initialized.
};

#endif
